package com.thinkingstar.iads.cs.sys.shiro;

import com.thinkingstar.iads.cs.sys.entity.SysRoleResource;
import com.thinkingstar.iads.cs.sys.entity.SysUser;
import com.thinkingstar.iads.datacenter.entity.dao.DaoDcProjectSysUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.nutz.integration.shiro.AbstractSimpleAuthorizingRealm;
import org.nutz.integration.shiro.SimpleShiroToken;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.mvc.Mvcs;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;


@IocBean
public class LoginRealm extends AbstractSimpleAuthorizingRealm {

    @Inject
    protected DaoDcProjectSysUser daoDcProjectSysUser;

//    @Inject
//    protected RetryLimitCredentialsMatcher retryLimitCredentialsMatcher;

    private static final String ADMIN = "system";

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //TODO 用户安全资源代码组装   资源：操作  就是按钮

        Subject   subject = SecurityUtils.getSubject();
        SysUser currUser = (SysUser)principals.fromRealm(getName()).iterator().next();
        //下面空指针
        if (daoDcProjectSysUser == null)
            daoDcProjectSysUser = Mvcs.ctx().getDefaultIoc().get(DaoDcProjectSysUser.class); // 取一次即可

        //当前用户的角色和资源按钮.
        List<SysRoleResource> role_list = daoDcProjectSysUser.getRoleByUserId(currUser.getId());
        //用户所拥有的权限
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> roles = new LinkedHashSet<>();
        Set<String> perms = new LinkedHashSet<>();
        for(SysRoleResource sysRoleResource : role_list) {
            roles.add(sysRoleResource.getRoleName());  //用户具有的角色
                if(Strings.isEmpty(sysRoleResource.getButton())){
                    continue;
                }
                perms.add(sysRoleResource.getResName() + ":" + sysRoleResource.getButton()+";"); //资源标识符号：资源按钮
        }
        info.addRoles(roles);
        info.addStringPermissions(perms);
        //此处写入session 用户  indexModule中/rolesAddPerms需要这个权限信息
        subject.getSession().setAttribute("authorizationInfo",info);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //TODO 用户登录鉴权信息
        String upToken = (String) token.getPrincipal();

        SysUser user =dao().fetch(SysUser.class, upToken);

        if (user == null){
            throw new LockedAccountException("账户不存在.");
        }

        if ("1".equalsIgnoreCase(String.valueOf(user.getState()))){
            throw new LockedAccountException("账户 [" + user.getLoginname() + "] 被禁用.");
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());

        return authenticationInfo;
    }

    protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
    }
    public LoginRealm() {
        this(null, null);
    }
    public LoginRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
        super(cacheManager, matcher);
        setAuthenticationTokenClass(SimpleShiroToken.class);
    }
    public LoginRealm(CacheManager cacheManager) {
        this(cacheManager, null);
    }
    public LoginRealm(CredentialsMatcher matcher) {
        this(null, matcher);
    }

    /**
     * 清除所有用户授权信息缓存.
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清除所有用户授权信息缓存.
     */
    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }
    /**
     *
     * @Title: clearAuthz
     * @Description: TODO 清除缓存的授权信息
     * @return void    返回类型
     */
    public void clearAuthz(){
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

}
